package com.tonggedata.dataapi.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.apache.dolphinscheduler.api.utils.PageInfo;

import org.springframework.stereotype.Service;
import cn.hutool.core.bean.BeanUtil;

import com.tonggedata.dataapi.entity.ApiRelationStrategyApi;
import com.tonggedata.dataapi.service.ApiRelationStrategyApiService;
import com.tonggedata.dataapi.mapper.ApiRelationStrategyApiMapper;
import com.tonggedata.dataapi.dto.ApiRelationStrategyApiDto;
import com.tonggedata.dataapi.dto.ApiRelationStrategyApiParamDto;
import com.tonggedata.dataapi.util.ApiServiceUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.dao.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.StrUtil;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;

/**
 * ==================================================
 *
 * @author : tonggedata
 * @fileName:
 * @create : 2022-06-19 13:08:47
 * @Description： api策略表与api关系表
 * ==================================================
 * @since 1.0.0
 */
@Service
public class ApiRelationStrategyApiServiceImpl extends ServiceImpl<ApiRelationStrategyApiMapper, ApiRelationStrategyApi> implements ApiRelationStrategyApiService {


    private static final Logger logger = LoggerFactory.getLogger(ApiRelationStrategyApiServiceImpl.class);

    @Autowired
    private ApiRelationStrategyApiMapper apiRelationStrategyApiMapper;

    @Override
    public Map<String, Object> queryApiRelationStrategyApi(long id) {
        Map<String, Object> result = new HashMap<>();
        ApiRelationStrategyApi apiRelationStrategyApi = getById(id);
        if (apiRelationStrategyApi == null) {
//            putMsg(result, Status.RESOURCE_NOT_EXIST);
            return result;
        }
        // type
        ApiRelationStrategyApiDto apiRelationStrategyApiDto = new ApiRelationStrategyApiDto();
        BeanUtil.copyProperties(apiRelationStrategyApi, apiRelationStrategyApiDto);

        result.put(Constants.DATA_LIST, apiRelationStrategyApiDto);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);
        return result;
    }


    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<Object> delete(User loginUser, long id) {
        Result<Object> result = new Result<>();
        try {
            //query datasource by id
            ApiRelationStrategyApi apiRelationStrategyApi = getById(id);
            if (apiRelationStrategyApi == null) {
                logger.error("resource id {} not exist" , id);
                ApiServiceUtil.putMsg(result, Status.RESOURCE_NOT_EXIST);
                return result;
            }
            if (!ApiServiceUtil.hasPerm(loginUser, apiRelationStrategyApi.getCreateUser())) {
                ApiServiceUtil.putMsg(result, Status.USER_NO_OPERATION_PERM);
                return result;
            }
            apiRelationStrategyApiMapper.deleteById(id);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (Exception e) {
            logger.error("delete apiRelationStrategyApi error" , e);
            throw new RuntimeException("delete apiRelationStrategyApi error" );
        }
        return result;
    }

    @Override
    public Result queryApiRelationStrategyApiListPaging(User loginUser, String searchVal, Integer pageNo, Integer pageSize) {
        Result result = new Result();
        Page<ApiRelationStrategyApi> apiRelationStrategyApiPage = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<ApiRelationStrategyApi> lambdaQuery = new LambdaQueryWrapper<ApiRelationStrategyApi>();
        if (!ApiServiceUtil.isAdmin(loginUser)) {
            lambdaQuery.eq(ApiRelationStrategyApi::getCreateUser, loginUser.getUserName());
        }
        if (StrUtil.isNotEmpty(searchVal)) {
            //lambdaQuery.eq(ApiRelationStrategyApi::getName, searchVal);
        }
        IPage<ApiRelationStrategyApi> ipage = page(apiRelationStrategyApiPage, lambdaQuery);
        //转换格式
        PageInfo<ApiRelationStrategyApi> pageInfo = new PageInfo<>(pageNo, pageSize);
        pageInfo.setTotal((int) ipage.getTotal());
        pageInfo.setTotalList(ipage.getRecords());
        result.setData(pageInfo);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);
        return result;
    }

    @Override
    public Map<String, Object> queryApiRelationStrategyApiList(User loginUser, String name) {
        Map<String, Object> result = new HashMap<>();

        LambdaQueryWrapper<ApiRelationStrategyApi> lambdaQuery = new LambdaQueryWrapper<ApiRelationStrategyApi>();

        if (!ApiServiceUtil.isAdmin(loginUser)) {
            lambdaQuery.eq(ApiRelationStrategyApi::getCreateUser, loginUser.getUserName());
        }
        if (StrUtil.isNotEmpty(name)) {
//            lambdaQuery.like(ApiRelationStrategyApi::getName, name);
        }
        List<ApiRelationStrategyApi> apiRelationStrategyApiList = apiRelationStrategyApiMapper.selectList(lambdaQuery);

        result.put(Constants.DATA_LIST, apiRelationStrategyApiList);
        ApiServiceUtil.putMsg(result, Status.SUCCESS);

        return result;
    }


    @Override
    public Result<Object> updateApiRelationStrategyApi(long id, User loginUser, ApiRelationStrategyApiParamDto apiRelationStrategyApiParam) {
        //ApiRelationStrategyApiUtil.checkApiRelationStrategyApiParam(apiRelationStrategyApiParam);
        Result<Object> result = new Result<>();
        ApiRelationStrategyApi apiRelationStrategyApi = getById(id);
        if (apiRelationStrategyApi == null) {
            // putMsg(result, Status.RESOURCE_NOT_EXIST);
            return result;
        }

        if (!ApiServiceUtil.hasPerm(loginUser, apiRelationStrategyApi.getCreateUser())) {
            ApiServiceUtil.putMsg(result, Status.USER_NO_OPERATION_PERM);
            return result;
        }

        //check name can use or not
        /*if (!apiRelationStrategyApi.getName().trim().equals(apiRelationStrategyApi.getName()) && checkName(apiRelationStrategyApi.getName())) {
            //putMsg(result, Status.DATASOURCE_EXIST);
            return result;
        }*/

        BeanUtil.copyProperties(apiRelationStrategyApiParam, apiRelationStrategyApi, CopyOptions.create().setIgnoreNullValue(true));
        try {
            apiRelationStrategyApi.setUpdateTime(new Date());
            apiRelationStrategyApi.setUpdateUser(loginUser.getUserName());
            apiRelationStrategyApiMapper.updateById(apiRelationStrategyApi);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (DuplicateKeyException ex) {
            logger.error("Update apiRelationStrategyApi error." , ex);
            ApiServiceUtil.putMsg(result, Status.DATASOURCE_EXIST);
        }
        return result;
    }

    private boolean checkName(String name) {
        LambdaQueryWrapper<ApiRelationStrategyApi> lambdaQuery = new LambdaQueryWrapper<ApiRelationStrategyApi>();
//        lambdaQuery.eq(ApiRelationStrategyApi::getName, name);
        List<ApiRelationStrategyApi> apiRelationStrategyApiList = apiRelationStrategyApiMapper.selectList(lambdaQuery);
        return apiRelationStrategyApiList != null && !apiRelationStrategyApiList.isEmpty();
    }

    @Override
    public Result<Object> createApiRelationStrategyApi(User loginUser, ApiRelationStrategyApiParamDto apiRelationStrategyApiParam) {
        //DatasourceUtil.checkApiRelationStrategyApiParam(apiRelationStrategyApiParam);
        Result<Object> result = new Result<>();
        // check name can use or not
      /* if (checkName(apiRelationStrategyApiParam.getName())) {
            putMsg(result, Status.DATA_API_GROUP_ERROR);
            return result;
        }*/

        // build apiRelationStrategyApi
        ApiRelationStrategyApi apiRelationStrategyApi = new ApiRelationStrategyApi();
        Date now = new Date();


        //apiRelationStrategyApi.setCreateUser(loginUser.getUserName());
        BeanUtil.copyProperties(apiRelationStrategyApiParam, apiRelationStrategyApi, CopyOptions.create().setIgnoreNullValue(true));

        //apiRelationStrategyApi.setCreateTime(now);
        apiRelationStrategyApi.setUpdateTime(now);
        try {
            apiRelationStrategyApiMapper.insert(apiRelationStrategyApi);
            ApiServiceUtil.putMsg(result, Status.SUCCESS);
        } catch (DuplicateKeyException ex) {
            logger.error("Create apiRelationStrategyApi error." , ex);
            ApiServiceUtil.putMsg(result, Status.DATA_API_GROUP_ERROR);
        }

        return result;
    }

}
